﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using com.yoozoo.gta.Extension;
using Gameplay.PVE.Survivor;
using OWL.Rendering.HRP;
using UnityEditor;
using UnityEngine;
using UnityEngine.Profiling;
using Yoozoo.HRP.Runtime;

public class MapFogData : MonoBehaviour
{
    public int id;
    public SpriteRenderer renderer;
    public List<Transform> outside = new List<Transform>();
    public List<Transform> inside = new List<Transform>();
    public Transform center;
    private bool locked;
    public float alpha;
    public int imageSize = 256;

    public void ShowImage(bool rebuild = false)
    {
        Profiler.BeginSample("MapFogData.ShowImage.Rebuild");
        if (rebuild)
        {
            Rebuild();
        }
        Profiler.EndSample();
        Profiler.BeginSample("MapFogData.ShowImage.CalculatePoints");
        var outsides = new List<Vector3>();
        var left = float.MaxValue;
        var right = float.MinValue;
        var top = float.MinValue;
        var bottom = float.MaxValue;
        for (int i = 0; i < this.outside.Count; i++)
        {
            //outsides.Add(this.outside[i].position - renderer.transform.position);
            left = Mathf.Min(left, this.outside[i].position.x);
            right = Mathf.Max(right, this.outside[i].position.x);
            top = Mathf.Max(top, this.outside[i].position.z);
            bottom = Mathf.Min(bottom, this.outside[i].position.z);
            //outsides.Add(this.outside[i].position);
        }
        var max = Mathf.Max(right - left, top - bottom);
        var centerPoint = new Vector3(left + max / 2, transform.position.y, bottom + max / 2);
        for (int i = 0; i < this.outside.Count; i++)
        {
            outsides.Add(this.outside[i].position - centerPoint);
        }
        
        var insides = new List<Vector3>();
        for (int i = 0; i < this.inside.Count; i++)
        {
            insides.Add(this.inside[i].position - centerPoint);            
        }
        
        Profiler.EndSample();
        var mapWidth = max;
        var mapHeight = max;
        MapFogUtility.textureWidth = imageSize;
        MapFogUtility.textureHeight = imageSize;
        var image = MapFogUtility.CreateTexture(outsides,insides, mapWidth,mapHeight,alpha);
        var spriteRenderer = renderer;
        Profiler.BeginSample("MapFogData.ShowImage.CreateSprite");
        spriteRenderer.sprite = Sprite.Create(image, new Rect(0, 0, image.width, image.height), new Vector2(0.5f, 0.5f));
        Profiler.EndSample();
        spriteRenderer.transform.localScale = new Vector3(mapHeight / (MapFogUtility.textureWidth / 100f), mapWidth / (MapFogUtility.textureHeight / 100f), 1);
        spriteRenderer.transform.position = centerPoint;
    }
    
    public bool Locked()
    {
        return locked;
    }

    private void Rebuild()
    {
        if (renderer == null)
        {
            var renderer = new GameObject("Renderer");
            renderer.transform.SetParent(transform);
            renderer.transform.localPosition = Vector3.zero;
            renderer.transform.localEulerAngles = new Vector3(90, 0, 0);
            this.renderer = renderer.AddComponent<SpriteRenderer>();
        }
        outside.Clear();
        var child = transform.Find("Outside");
        if (child == null)
        {
            return;
        }
        for(int i = 0; i < child.childCount; i++)
        {
            var point = child.GetChild(i);
            outside.Add(point);
        }
        inside.Clear();
        child = transform.Find("Inside");
        if (child == null)
        {
            return;
        }

        for (int i = 0; i < child.childCount; i++)
        {
            var point = child.GetChild(i);
            inside.Add(point);
        }
    }
    
    public void Show(bool rebuild = false)
    {
        locked = false;
        /*if (rebuild)
        {
            Rebuild();
        }*/
        if (rebuild)
        {
            ShowImage(true);
        }
        /*var list = new List<Vector3>();
        for (int i = 0; i < points.Count; i++)
        {
            list.Add(points[i].localPosition);
        }

        var centerPosition = GetCenterPosition();
        //list.Add(points[0].position);
        GetComponent<MeshFilter>().mesh = MapFogUtility.CreateMeshByPoints(list,centerPosition);*/
        gameObject.SetActive(true);
    }

    public void SaveImage()
    {
#if UNITY_EDITOR
        if (renderer.sprite)
        {
            var texture = renderer.sprite.texture;
            byte[] dataBytes = texture.EncodeToPNG();
            string path = Application.dataPath + "/ResourcesAssets/Pve/Survivor/Textures/Map/" + name + ".png";
            FileStream fileSteam = File.Open(path, FileMode.OpenOrCreate);
            fileSteam.Write(dataBytes, 0, dataBytes.Length);
            fileSteam.Close();
            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();

            var sprite = AssetDatabase.LoadAssetAtPath<Sprite>(path);
            Debug.LogError(sprite);
            renderer.sprite = sprite;
            //texture = AssetDatabase.LoadAssetAtPath<Texture2D>(path);
            //renderer.sprite = AssetDatabase.LoadAssetAtPath<Texture2D>(path).ToSprite();
        }
#endif
    }

    public void Hide()
    {
        locked = true;
        gameObject.SetActive(false);
    }

    public Vector3 GetCenterPosition()
    {
        /*var centerPosition = Vector3.zero;
        if (center != null)
        {
            centerPosition = center.localPosition;
        }
        else
        {
            for (int i = 0; i < points.Count; i++)
            {
                centerPosition += points[i].localPosition;
            }
            centerPosition /= points.Count;
        }*/
        return transform.position;
        //return centerPosition;
    }

    public Vector3 GetCenterWorldPosition()
    {
        if (renderer)
        {
            return renderer.transform.position;
        }
        return transform.position;
    }
    
    private void OnDrawGizmos()
    {
        for (int i = 0; i < outside.Count; i++)
        {
            if (!outside[i] || outside[(i + 1) % outside.Count])
            {
                return;
            }
            Gizmos.color = Color.blue;
            Gizmos.DrawLine(outside[i].position, outside[(i + 1) % outside.Count].position);
        }
        for (int i = 0; i < inside.Count; i++)
        {
            if (!inside[i] || inside[(i + 1) % inside.Count])
            {
                return;
            }
            Gizmos.color = Color.magenta;
            Gizmos.DrawLine(inside[i].position, inside[(i + 1) % inside.Count].position);
        }
    }
}